package com.googlecode.controlecheque.database;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

import com.googlecode.controlecheque.database.helper.DatabaseHelper;

/**
 * Provides access to a database of notes. Each note has a title, the note
 * itself, a creation date and a modified data.
 */
public class DatabaseProvider extends ContentProvider {

	private static HashMap<String, String> chequeProjectionMap;
	private static HashMap<String, String> bancoProjectionMap;

	private static final int CHEQUE = 1;
	private static final int CHEQUE_ID = 2;

	private static final int BANCO = 3;
	private static final int BANCO_ID = 4;

	private static final UriMatcher uriMatcher;

	private DatabaseHelper databaseHelper;

	@Override
	public boolean onCreate() {
		databaseHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

		switch (uriMatcher.match(uri)) {
		case CHEQUE:
			qb.setTables(Cheque.TABLE_NAME);
			qb.setProjectionMap(chequeProjectionMap);
			break;
		case CHEQUE_ID:
			qb.setTables(Cheque.TABLE_NAME);
			qb.setProjectionMap(chequeProjectionMap);
			qb.appendWhere(Cheque._ID + "=" + uri.getPathSegments().get(1));
			break;

		case BANCO:
			qb.setTables(Banco.TABLE_NAME);
			qb.setProjectionMap(bancoProjectionMap);
			break;
		case BANCO_ID:
			qb.setTables(Banco.TABLE_NAME);
			qb.setProjectionMap(bancoProjectionMap);
			qb.appendWhere(Banco._ID + "=" + uri.getPathSegments().get(1));
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		String orderBy;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = Cheque.DEFAULT_SORT_ORDER;
		} else {
			orderBy = sortOrder;
		}

		SQLiteDatabase db = databaseHelper.getReadableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case CHEQUE:
			return Cheque.CONTENT_TYPE;
		case CHEQUE_ID:
			return Cheque.CONTENT_ITEM_TYPE;

		case BANCO:
			return Banco.CONTENT_TYPE;
		case BANCO_ID:
			return Banco.CONTENT_ITEM_TYPE;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {
		if (uriMatcher.match(uri) == CHEQUE) {
			return inserirCheque(uri, initialValues);
		} else if (uriMatcher.match(uri) == BANCO) {
			return inserirBanco(uri, initialValues);
		} else {
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	public Uri inserirCheque(Uri uri, ContentValues initialValues) {
		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		if (values.containsKey(Cheque.AGENCIA) == false) {
			values.put(Cheque.AGENCIA, "");
		}
		if (values.containsKey(Cheque.CONTA) == false) {
			values.put(Cheque.CONTA, "");
		}
		if (values.containsKey(Cheque.NUMERO_CHEQUE) == false) {
			values.put(Cheque.NUMERO_CHEQUE, "");
		}
		if (values.containsKey(Cheque.VALOR) == false) {
			values.put(Cheque.VALOR, "");
		}

		SQLiteDatabase db = databaseHelper.getWritableDatabase();
		long rowId = db.insert(Cheque.TABLE_NAME, null, values);
		if (rowId > 0) {
			Uri noteUri = ContentUris.withAppendedId(Cheque.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(noteUri, null);
			return noteUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	public Uri inserirBanco(Uri uri, ContentValues initialValues) {
		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		if (values.containsKey(Banco.CD_BANCO) == false) {
			values.put(Banco.CD_BANCO, "");
		}
		if (values.containsKey(Banco.NM_BANCO) == false) {
			values.put(Banco.NM_BANCO, "");
		}

		SQLiteDatabase db = databaseHelper.getWritableDatabase();
		long rowId = db.insert(Banco.TABLE_NAME, null, values);
		if (rowId > 0) {
			Uri noteUri = ContentUris.withAppendedId(Banco.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(noteUri, null);
			return noteUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = databaseHelper.getWritableDatabase();
		int count;
		switch (uriMatcher.match(uri)) {
		case CHEQUE:
			count = db.delete(Cheque.TABLE_NAME, where, whereArgs);
			break;
		case CHEQUE_ID:
			String chequeId = uri.getPathSegments().get(1);
			count = db.delete(Cheque.TABLE_NAME, Cheque._ID + "=" + chequeId
					+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		case BANCO:
			count = db.delete(Banco.TABLE_NAME, where, whereArgs);
			break;
		case BANCO_ID:
			String bancoId = uri.getPathSegments().get(1);
			count = db.delete(Banco.TABLE_NAME, Banco._ID + "=" + bancoId
					+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
		SQLiteDatabase db = databaseHelper.getWritableDatabase();
		int count;
		switch (uriMatcher.match(uri)) {
		case CHEQUE:
			count = db.update(Cheque.TABLE_NAME, values, where, whereArgs);
			break;
		case CHEQUE_ID:
			String chequeId = uri.getPathSegments().get(1);
			count = db.update(Cheque.TABLE_NAME, values, Cheque._ID + "=" + chequeId
					+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		case BANCO:
			count = db.update(Banco.TABLE_NAME, values, where, whereArgs);
			break;
		case BANCO_ID:
			String bancoId = uri.getPathSegments().get(1);
			count = db.update(Banco.TABLE_NAME, values, Banco._ID + "=" + bancoId
					+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(Cheque.AUTHORITY, "cheque", CHEQUE);
		uriMatcher.addURI(Cheque.AUTHORITY, "cheque/#", CHEQUE_ID);

		uriMatcher.addURI(Banco.AUTHORITY, "banco", BANCO);
		uriMatcher.addURI(Banco.AUTHORITY, "banco/#", BANCO_ID);

		chequeProjectionMap = new HashMap<String, String>();
		chequeProjectionMap.put(Cheque._ID, Cheque._ID);
		chequeProjectionMap.put(Cheque.BANCO, Cheque.BANCO);
		chequeProjectionMap.put(Cheque.AGENCIA, Cheque.AGENCIA);
		chequeProjectionMap.put(Cheque.CONTA, Cheque.CONTA);
		chequeProjectionMap.put(Cheque.NUMERO_CHEQUE, Cheque.NUMERO_CHEQUE);
		chequeProjectionMap.put(Cheque.VALOR, Cheque.VALOR);
		chequeProjectionMap.put(Cheque.DATA_EMISSAO, Cheque.DATA_EMISSAO);
		chequeProjectionMap.put(Cheque.DATA_VENCIMENTO, Cheque.DATA_VENCIMENTO);
		chequeProjectionMap.put(Cheque.CORRENTISTA, Cheque.CORRENTISTA);
		chequeProjectionMap.put(Cheque.CLIENTE, Cheque.CLIENTE);
		chequeProjectionMap.put(Cheque.SITUACAO, Cheque.SITUACAO);

		bancoProjectionMap = new HashMap<String, String>();
		bancoProjectionMap.put(Banco._ID, Banco._ID);
		bancoProjectionMap.put(Banco.CD_BANCO, Banco.CD_BANCO);
		bancoProjectionMap.put(Banco.NM_BANCO, Banco.NM_BANCO);
	}
}
